package main

import (
	"fmt"
	"os"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/google/uuid"
	"github.com/nats-io/go-nats"
	"github.com/nats-io/go-nats-streaming"
)

var stanc stan.Conn
var stancClose = make(chan struct{}, 1)
var initOk int8

func StanConnect() (sc stan.Conn, err error) {
	NatsURL := os.Getenv("NATS_URL")
	if NatsURL == "" {
		return nil, fmt.Errorf("NATS_URL is null ")
	}

	NatsToken := os.Getenv("NATS_TOKEN")
	stanClusterID := os.Getenv("NATS_STREAMING_CLUSTER_ID")
	if stanClusterID == "" {
		stanClusterID = "test-cluster"
	}

	conn, err := nats.Connect(NatsURL, nats.Token(NatsToken))
	if err != nil {
		return
	}

	clientID := uuid.New().String()
	stanc, err = stan.Connect(stanClusterID,
		clientID,
		stan.NatsConn(conn),
		stan.Pings(10, 5),
		stan.SetConnectionLostHandler(func(conn stan.Conn, e error) {
			logrus.WithError(e).Error("SetConnectionLostHandler")
			logrus.WithError(stanc.Close()).Error("stan close")
			stancClose <- struct{}{}
		}),
	)

	if initOk == 0 {
		reconnectHandler()
	}

	return
}

func GetStan() (sc stan.Conn, err error) {
	if stanc == nil {
		return StanConnect()
	}

	//for range stancClose {
	//	return StanConnect()
	//}

	return stanc, nil
}

func reconnectHandler() {
	initOk = 1
	go func() {
		for {
			select {
			case <-stancClose:
				_, err := StanConnect()
				if err != nil {
					logrus.WithError(err).Error("stan reconnect 重连失败，等待下次重连")
					stancClose <- struct{}{}
					break
				}
				logrus.Println("stan reconnect ok")
			case <-time.After(time.Second):
				break
			}
			time.Sleep(time.Second * 5)
		}
	}()
}
